﻿
namespace SistemaLogistica.DataAccess
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using SistemaLogistica.Business.Entities;

    public class AsignacionData : BaseDataAccess
    {
        private AsignacionData() { }

        private readonly static AsignacionData instancia = new AsignacionData();

        public static AsignacionData Instancia
        {
            get { return instancia; }
        }

        public List<Asignacion> ListarPorTipo(int tipo)
        {
            List<Asignacion> asignaciones = new List<Asignacion>();

            DbCommand command = db.GetStoredProcCommand("GetAsignacionByTipo");
            db.AddInParameter(command, "tipo", DbType.Int32, tipo);

            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    asignaciones.Add(new Asignacion
                    {
                        IdAsignacion = dr.GetInt32(dr.GetOrdinal("IdAsignacion")),
                        Fecha = dr.GetDateTime(dr.GetOrdinal("Fecha")),
                        Empleados = EmpleadoData.Instancia.ObtenerPorID(dr.GetInt16(dr.GetOrdinal("IdEmpleado"))),
                        NotaSalida = NotaSalidaData.Instancia.ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdNotaSalida"))),
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),                     
                        Tipo = dr.GetInt32(dr.GetOrdinal("Tipo"))                        
                    });
                }
            }
            return asignaciones;
        }

        public List<Asignacion> Buscar(DateTime desde, DateTime hasta, int tipo)
        {
            List<Asignacion> asignaciones = new List<Asignacion>();

            DbCommand command = db.GetStoredProcCommand("SearchAsignacion");
            db.AddInParameter(command, "desde", DbType.DateTime, desde);
            db.AddInParameter(command, "hasta", DbType.DateTime, hasta);
            db.AddInParameter(command, "tipo", DbType.Int32, tipo);

            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    asignaciones.Add(new Asignacion
                    {
                        IdAsignacion = dr.GetInt32(dr.GetOrdinal("IdAsignacion")),
                        Fecha = dr.GetDateTime(dr.GetOrdinal("Fecha")),
                        Empleados = EmpleadoData.Instancia.ObtenerPorID(dr.GetInt16(dr.GetOrdinal("IdEmpleado"))),
                        NotaSalida = NotaSalidaData.Instancia.ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdNotaSalida"))),
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        Tipo = dr.GetInt32(dr.GetOrdinal("Tipo")) 
                    });
                }
            }
            return asignaciones;
        }

        public Asignacion ObtenerPorID(int idAsignacion)
        {
            Asignacion asignacion = null;
            DbCommand command = db.GetStoredProcCommand("GetAsignacionByIdAsignacion");
            db.AddInParameter(command, "idAsignacion", DbType.Int32, idAsignacion);

            using (IDataReader dr = db.ExecuteReader(command))
            {
                if (dr.Read())
                {
                    asignacion = new Asignacion
                    {
                        IdAsignacion = dr.GetInt32(dr.GetOrdinal("IdAsignacion")),
                        Fecha = dr.GetDateTime(dr.GetOrdinal("Fecha")),
                        Empleados = EmpleadoData.Instancia.ObtenerPorID(dr.GetInt16(dr.GetOrdinal("IdEmpleado"))),
                        NotaSalida = NotaSalidaData.Instancia.ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdNotaSalida"))),
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        Tipo = dr.GetInt32(dr.GetOrdinal("Tipo")),
                        Detalle = DetalleAsignacionData.Instancia.ListarPorAsignacion(idAsignacion)
                    };
                }
            }
            return asignacion;
        }

        public void Registrar(Asignacion asignacion)
        {
            using (DbConnection conection = db.CreateConnection())
            {
                conection.Open();
                using (DbTransaction transaction = conection.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdAsignacion = db.GetStoredProcCommand("InsertAsignacion");
                        db.AddInParameter(cmdAsignacion, "descripcion", DbType.String, asignacion.Descripcion);
                        db.AddInParameter(cmdAsignacion, "fecha", DbType.DateTime, asignacion.Fecha);
                        db.AddOutParameter(cmdAsignacion, "idAsignacion", DbType.Int32, 11);
                        db.AddInParameter(cmdAsignacion, "idEmpleado", DbType.Int16, asignacion.Empleados.IdEmpleado);
                        db.AddInParameter(cmdAsignacion, "idNotaSalida", DbType.Int32, asignacion.NotaSalida.IdNotaSalida);
                        db.AddInParameter(cmdAsignacion, "tipo", DbType.Int32, asignacion.Tipo);

                        int result = db.ExecuteNonQuery(cmdAsignacion, transaction);
                        if (result == 0) throw new Exception("Error al Registrar Asignación.");

                        int idAsignacion = Convert.ToInt32(db.GetParameterValue(cmdAsignacion, "idAsignacion"));

                        DbCommand cmdDetalle = db.GetStoredProcCommand("InsertDetalleAsignacion");
                        db.AddInParameter(cmdDetalle, "cantidad", DbType.Decimal);
                        db.AddInParameter(cmdDetalle, "comentario", DbType.String);
                        db.AddInParameter(cmdDetalle, "idAsignacion", DbType.Int32);
                        db.AddInParameter(cmdDetalle, "idBien", DbType.Int32);
                        db.AddInParameter(cmdDetalle, "idEmpleado", DbType.Int16);

                        foreach (DetalleAsignacion d in asignacion.Detalle)
                        {
                            db.SetParameterValue(cmdDetalle, "cantidad", d.Cantidad);
                            db.SetParameterValue(cmdDetalle, "comentario", d.Comentario);
                            db.SetParameterValue(cmdDetalle, "idAsignacion", idAsignacion);
                            db.SetParameterValue(cmdDetalle, "idBien", d.Bien.IdBien);
                            db.SetParameterValue(cmdDetalle, "idEmpleado", d.Empleados.IdEmpleado);
                            db.ExecuteNonQuery(cmdDetalle, transaction);
                        }

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void Actualizar(Asignacion asignacion)
        {
            using (DbConnection conection = db.CreateConnection())
            {
                conection.Open();
                using (DbTransaction transaction = conection.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdAsignacion = db.GetStoredProcCommand("UpdateAsignacion");
                        db.AddInParameter(cmdAsignacion, "descripcion", DbType.String, asignacion.Descripcion);
                        db.AddInParameter(cmdAsignacion, "fecha", DbType.DateTime, asignacion.Fecha);
                        db.AddInParameter(cmdAsignacion, "idAsignacion", DbType.Int32, asignacion.IdAsignacion);
                        db.AddInParameter(cmdAsignacion, "idEmpleado", DbType.Int16, asignacion.Empleados.IdEmpleado);
                        db.AddInParameter(cmdAsignacion, "idNotaSalida", DbType.Int32, asignacion.NotaSalida.IdNotaSalida);
                        db.AddInParameter(cmdAsignacion, "tipo", DbType.Int32, asignacion.Tipo);

                        int result = db.ExecuteNonQuery(cmdAsignacion, transaction);
                        if (result == 0) throw new Exception("Error al Modificar Asignación.");

                        DbCommand cmdEliminar = db.GetStoredProcCommand("DeleteDetalleAsignacionByIdAsignacion");
                        db.AddInParameter(cmdEliminar, "idAsignacion", DbType.Int32, asignacion.IdAsignacion);
                        db.ExecuteNonQuery(cmdEliminar);

                        DbCommand cmdDetalle = db.GetStoredProcCommand("InsertDetalleAsignacion");
                        db.AddInParameter(cmdDetalle, "cantidad", DbType.Decimal);
                        db.AddInParameter(cmdDetalle, "comentario", DbType.String);
                        db.AddInParameter(cmdDetalle, "idAsignacion", DbType.Int32);
                        db.AddInParameter(cmdDetalle, "idBien", DbType.Int32);
                        db.AddInParameter(cmdDetalle, "idEmpleado", DbType.Int16);

                        foreach (DetalleAsignacion d in asignacion.Detalle)
                        {
                            db.SetParameterValue(cmdDetalle, "cantidad", d.Cantidad);
                            db.SetParameterValue(cmdDetalle, "comentario", d.Comentario);
                            db.SetParameterValue(cmdDetalle, "idAsignacion", asignacion.IdAsignacion);
                            db.SetParameterValue(cmdDetalle, "idBien", d.Bien.IdBien);
                            db.SetParameterValue(cmdDetalle, "idEmpleado", d.Empleados.IdEmpleado);
                            db.ExecuteNonQuery(cmdDetalle, transaction);
                        }

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void Eliminar(int idAsignacion)
        {
            DbCommand command = db.GetStoredProcCommand("DeleteAsignacion");
            db.AddInParameter(command, "idAsignacion", DbType.Int32, idAsignacion);

            int result = db.ExecuteNonQuery(command);
            if (result == 0) throw new Exception("Error al Eliminar Asignación.");
        }
    }
}

